package com.qf.shiro2204.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.shiro2204.user.entity.*;
import com.qf.shiro2204.user.mapper.*;
import com.qf.shiro2204.user.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.shiro2204.utils.Constants;
import com.qf.shiro2204.utils.SaltUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dong
 * @since 2023-04-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    TUserRoleMapper tUserRoleMapper;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    TRoleMapper tRoleMapper;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    TRolePermsMapper tRolePermsMapper;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    TPersMapper tPersMapper;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void regist(String username, String password) {

        //1. 查询当前用户名在数据库中是否存在，如果存在就抛异常
        User dbuser = this.getOne(new QueryWrapper<User>().eq("username", username));
//        User dbuser = this.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername,username));
        if (dbuser!=null){
            throw new RuntimeException("用户名已存在");
        }
        //2. 处理密码
        //2.1 生成随机盐
        String salt = SaltUtils.genSalt(Constants.SALT_LENTH);
        String md5password = new Md5Hash(password, salt, Constants.HASH_TIMES).toHex();

        //3. 入库
        User user = new User();
        user.setUsername(username);
        user.setSalt(salt);
        user.setPassword(md5password);

        this.save(user);

    }

    @Override
    public List<String> getRoles(User user) {

        // mp中获取 Dao对象的方法
        UserDao userDao = this.getBaseMapper();

        List<String> result = userDao.getRoles(user.getId());

        return result;
    }


    @Override
    public List<String> getPerms(User user) {

        UserDao userDao = this.getBaseMapper();

        List<String> permsList = userDao.getPerms(user.getId());

        // 权限字符串去重
        List<String> result = permsList.stream().distinct().collect(Collectors.toList());

        return result;
    }

    @Override
    public List<String> getRolesByMpAPI(User user) {

        //1. 根据用户id查询该用户有哪些角色 id   userid ---->  List<角色ID>
        // SELECT roleid FROM t_user_role WHERE userid=2;
        List<Object> roleIdList =
                tUserRoleMapper.selectObjs(new QueryWrapper<TUserRole>().select("roleid").eq("userid", user.getId()));

        //2. 根据查到的List<角色ID> ，获取角色的name。 List<角色ID>----> List<角色名>
        // SELECT NAME FROM t_role WHERE id IN (1,2);
        List<Object> roleNameList = tRoleMapper.selectObjs(new QueryWrapper<TRole>().select("name").in("id", roleIdList));

        //3. 类型转换 List<Object> ---> List<String>
//        ArrayList<String> result = new ArrayList<>();
//        for (Object o : roleNameList) {
//            result.add(o.toString());
//        }
        List<String> result = roleNameList.stream().map(o -> o.toString()).collect(Collectors.toList());
//        List<String> result = roleNameList.stream().map(Object::toString).collect(Collectors.toList());

        return result;
    }

    @Override
    public List<String> getPermsByMpAPI(User user) {

        // SELECT roleid FROM t_user_role WHERE userid=2;
        List<Object> roleIdList =
                tUserRoleMapper.selectObjs(new QueryWrapper<TUserRole>().select("roleid").eq("userid", user.getId()));

        // SELECT permsid FROM t_role_perms WHERE roleid IN (1,2);
        List<Object> permIdList =
                tRolePermsMapper.selectObjs(new QueryWrapper<TRolePerms>().select("permsid").in("roleid", roleIdList));

        // SELECT NAME FROM t_pers WHERE id IN (1,2,3,4,5,6);
        List<Object> permsObjList = tPersMapper.selectObjs(new QueryWrapper<TPers>().select("name").in("id", permIdList));

        // List<Object> ==> List<String>
        List<String> result = permsObjList.stream()
                .distinct() // 去重
                .map(o -> o.toString())
                .collect(Collectors.toList());

        return result;
    }
}
